home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / mozilla-firefox / include / necko / nsReadLine.h < prev    next >
C/C++ Source or Header  |  2006-05-08  |  7KB  |  213 lines

  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * ***** BEGIN LICENSE BLOCK *****
  4.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  5.  *
  6.  * The contents of this file are subject to the Mozilla Public License Version
  7.  * 1.1 (the "License"); you may not use this file except in compliance with
  8.  * the License. You may obtain a copy of the License at
  9.  * http://www.mozilla.org/MPL/
  10.  *
  11.  * Software distributed under the License is distributed on an "AS IS" basis,
  12.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13.  * for the specific language governing rights and limitations under the
  14.  * License.
  15.  *
  16.  * The Original Code is mozilla.org code.
  17.  *
  18.  * The Initial Developer of the Original Code is
  19.  * Boris Zbarsky <bzbarsky@mit.edu>.
  20.  * Portions created by the Initial Developer are Copyright (C) 2001
  21.  * the Initial Developer. All Rights Reserved.
  22.  *
  23.  * Contributor(s):
  24.  *   Christian Biesinger <cbiesinger@web.de>
  25.  *
  26.  * Alternatively, the contents of this file may be used under the terms of
  27.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  28.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  29.  * in which case the provisions of the GPL or the LGPL are applicable instead
  30.  * of those above. If you wish to allow use of your version of this file only
  31.  * under the terms of either the GPL or the LGPL, and not to allow others to
  32.  * use your version of this file under the terms of the MPL, indicate your
  33.  * decision by deleting the provisions above and replace them with the notice
  34.  * and other provisions required by the GPL or the LGPL. If you do not delete
  35.  * the provisions above, a recipient may use your version of this file under
  36.  * the terms of any one of the MPL, the GPL or the LGPL.
  37.  *
  38.  * ***** END LICENSE BLOCK ***** */
  39.  
  40. #ifndef nsReadLine_h__
  41. #define nsReadLine_h__
  42.  
  43. #include "prmem.h"
  44. #include "nsIInputStream.h"
  45.  
  46. /**
  47.  * @file
  48.  * Functions to read complete lines from an input stream.
  49.  *
  50.  * To properly use the helper function in here (NS_ReadLine) the caller
  51.  * needs to declare a pointer to an nsLineBuffer, call
  52.  * NS_InitLineBuffer on it, and pass it to NS_ReadLine every time it
  53.  * wants a line out.
  54.  *
  55.  * When done, the pointer should be freed using PR_Free.
  56.  */
  57.  
  58. /**
  59.  * @internal
  60.  * Buffer size. This many bytes will be buffered. If a line is longer than this,
  61.  * the partial line will be appended to the out parameter of NS_ReadLine and the
  62.  * buffer will be emptied.
  63.  */
  64. #define kLineBufferSize 1024
  65.  
  66. /**
  67.  * @internal
  68.  * Line buffer structure, buffers data from an input stream.
  69.  */
  70. template<typename CharT>
  71. class nsLineBuffer {
  72.   public:
  73.   CharT buf[kLineBufferSize+1];
  74.   CharT* start;
  75.   CharT* current;
  76.   CharT* end;
  77.   PRBool empty;
  78. };
  79.  
  80. /**
  81.  * Initialize a line buffer for use with NS_ReadLine.
  82.  *
  83.  * @param aBufferPtr
  84.  *        Pointer to pointer to a line buffer. Upon successful return,
  85.  *        *aBufferPtr will contain a valid pointer to a line buffer, for use
  86.  *        with NS_ReadLine. Use PR_Free when the buffer is no longer needed.
  87.  *
  88.  * @retval NS_OK Success.
  89.  * @retval NS_ERROR_OUT_OF_MEMORY Not enough memory to allocate the line buffer.
  90.  *
  91.  * @par Example:
  92.  * @code
  93.  *    nsLineBuffer* lb;
  94.  *    rv = NS_InitLineBuffer(&lb);
  95.  *    if (NS_SUCCEEDED(rv)) {
  96.  *      // do stuff...
  97.  *      PR_Free(lb);
  98.  *    }
  99.  * @endcode
  100.  */
  101. template<typename CharT>
  102. nsresult
  103. NS_InitLineBuffer (nsLineBuffer<CharT> ** aBufferPtr) {
  104.   *aBufferPtr = PR_NEW(nsLineBuffer<CharT>);
  105.   if (!(*aBufferPtr))
  106.     return NS_ERROR_OUT_OF_MEMORY;
  107.  
  108.   (*aBufferPtr)->start = (*aBufferPtr)->current = (*aBufferPtr)->end = (*aBufferPtr)->buf;
  109.   (*aBufferPtr)->empty = PR_TRUE;
  110.   return NS_OK;
  111. }
  112.  
  113. /**
  114.  * Read a line from an input stream. Lines are separated by '\r' (0x0D) or '\n'
  115.  * (0x0A), or "\r\n" or "\n\r".
  116.  *
  117.  * @param aStream
  118.  *        The stream to read from
  119.  * @param aBuffer
  120.  *        The line buffer to use. Must have been inited with
  121.  *        NS_InitLineBuffer before. A single line buffer must not be used with
  122.  *        different input streams.
  123.  * @param aLine [out]
  124.  *        The string where the line will be stored.
  125.  * @param more [out]
  126.  *        Whether more data is available in the buffer. If true, NS_ReadLine may
  127.  *        be called again to read further lines. Otherwise, further calls to
  128.  *        NS_ReadLine will return an error.
  129.  *
  130.  * @retval NS_OK
  131.  *         Read successful
  132.  * @retval error
  133.  *         Input stream returned an error upon read. See
  134.  *         nsIInputStream::read.
  135.  */
  136. template<typename CharT, class StreamType, class StringType>
  137. nsresult
  138. NS_ReadLine (StreamType* aStream, nsLineBuffer<CharT> * aBuffer,
  139.              StringType & aLine, PRBool *more) {
  140.   nsresult rv = NS_OK;
  141.   PRUint32 bytesRead;
  142.   *more = PR_TRUE;
  143.   PRBool eolStarted = PR_FALSE;
  144.   CharT eolchar = '\0';
  145.   aLine.Truncate();
  146.   while (1) { // will be returning out of this loop on eol or eof
  147.     if (aBuffer->empty) { // buffer is empty.  Read into it.
  148.       rv = aStream->Read(aBuffer->buf, kLineBufferSize, &bytesRead);
  149.       if (NS_FAILED(rv)) // read failed
  150.         return rv;
  151.       if (bytesRead == 0) { // end of file
  152.         *more = PR_FALSE;
  153.         return NS_OK;
  154.       }
  155.       aBuffer->end = aBuffer->buf + bytesRead;
  156.       aBuffer->empty = PR_FALSE;
  157.       *(aBuffer->end) = '\0'; // null-terminate this thing
  158.     }
  159.     // walk the buffer looking for an end-of-line
  160.     while (aBuffer->current < aBuffer->end) {
  161.       if (eolStarted) {
  162.           if ((eolchar == '\n' && *(aBuffer->current) == '\r') ||
  163.               (eolchar == '\r' && *(aBuffer->current) == '\n')) { // line end
  164.             (aBuffer->current)++;
  165.             aBuffer->start = aBuffer->current;
  166.           }
  167.           eolStarted = PR_FALSE;
  168.           return NS_OK;
  169.       } else if (*(aBuffer->current) == '\n' ||
  170.                  *(aBuffer->current) == '\r') { // line end
  171.         eolStarted = PR_TRUE;
  172.         eolchar = *(aBuffer->current);
  173.         *(aBuffer->current) = '\0';
  174.         aLine.Append(aBuffer->start);
  175.         (aBuffer->current)++;
  176.         aBuffer->start = aBuffer->current;
  177.       } else {
  178.         eolStarted = PR_FALSE;
  179.         (aBuffer->current)++;
  180.       }
  181.     }
  182.  
  183.     // append whatever we currently have to the string
  184.     aLine.Append(aBuffer->start);
  185.  
  186.     // we've run out of buffer.  Begin anew
  187.     aBuffer->current = aBuffer->start = aBuffer->buf;
  188.     aBuffer->empty = PR_TRUE;
  189.     
  190.     if (eolStarted) {  // have to read another char and possibly skip over it
  191.       rv = aStream->Read(aBuffer->buf, 1, &bytesRead);
  192.       if (NS_FAILED(rv)) // read failed
  193.         return rv;
  194.       if (bytesRead == 0) { // end of file
  195.         *more = PR_FALSE;
  196.         return NS_OK;
  197.       }
  198.       if ((eolchar == '\n' && *(aBuffer->buf) == '\r') ||
  199.           (eolchar == '\r' && *(aBuffer->buf) == '\n')) {
  200.         // Just return and all is good -- we've skipped the extra newline char
  201.         return NS_OK;
  202.       } else {
  203.         // we have a byte that we should look at later
  204.         aBuffer->empty = PR_FALSE;
  205.         aBuffer->end = aBuffer->buf + 1;
  206.         *(aBuffer->end) = '\0';
  207.       }
  208.     }
  209.   }
  210. }
  211.  
  212. #endif // nsReadLine_h__
  213.